import os
import requests
import threading
import queue
import time
from model.utils.my_utils import get_apkinfo, get_ret, unzip_apk
from django.shortcuts import render, redirect
from django.core.files.storage import FileSystemStorage
from django.http import JsonResponse, HttpResponseRedirect
from concurrent.futures import ThreadPoolExecutor, as_completed
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt
import json
from blacklist.models import APK
from django.http import FileResponse
from commonutils.minioutils import get_file_list

def index(request):
    return render(request,'client/index.html')

def historical_record(request):
    apks = APK.objects.all()
    return render(request, 'client/historical_record.html',{'apks':apks})

def apk_details(request,apk_id):
    try:
        apk = APK.objects.get(pk=apk_id)
    except Exception as e:
        apk=None
    return render(request,'client/apk_detail.html',locals())

def upload_file(request):
    if request.method == 'POST':
        file_to_upload = request.FILES['fileToUpload']
        # 处理上传的文件
        upload_dir = 'apkfilter'
        if not os.path.exists(upload_dir):
            os.makedirs(upload_dir)
        file_path = os.path.join(upload_dir, file_to_upload.name)
        with open(file_path, 'wb+') as destination:
            for chunk in file_to_upload.chunks():
                destination.write(chunk)
        file_names = file_to_upload.name
        result_queue = queue.Queue()
        threads = []
        for file_name in file_names:
            thread = threading.Thread(target=worker, args=(file_name, result_queue))
            threads.append(thread)
            thread.start()
        results = {}
        while not result_queue.empty():
            file_name, info, apkinfo = result_queue.get()
            if info is None:
                print(f"Error processing {file_name}: {apkinfo}")
            else:
                results[file_name] = (info, apkinfo)
                print(f"Result for {file_name}:")
                print(f"  Info: {info}")
                print(f"  APK Info: {apkinfo}")
        # (apk_filename,activities,package,permissions,app_name,version_name,version_code,
        #  hash_algo,serial_number,contents_der,issuer,md5,sha1,sha256,validity_period
        #  ,signature_algo,intent,icon_url,apk_size,folder_size)
        attributes = dir(apkinfo)
        attribute_dict = {}
        for attr_name in attributes:
            value = getattr(apkinfo, attr_name, None)
            if not attr_name.startswith("__") and not callable(value):
                attribute_dict[attr_name] = value
        new_apk = APK()
        for key,value in attribute_dict.items():
            if hasattr(new_apk,key):
                setattr(new_apk,key,value)
        new_apk.ret=get_ret(info)[0]
        new_apk.save()
        url = reverse('apk_detail', args=[new_apk.id])
        return redirect(url)
    return render(request, 'client/index.html')

def worker(file_name, result_queue):
    try:
        info, apkinfo = get_apkinfo(file_name)
        result_queue.put((file_name, info, apkinfo))
    except Exception as e:
        result_queue.put((file_name, None, str(e)))

def apk_unzip(request):
    if request.method == 'POST':
        file_to_upload = request.FILES['files8']
        # 处理上传的文件
        upload_dir = 'apkfilter'
        if not os.path.exists(upload_dir):
            os.makedirs(upload_dir)

        # 构建文件保存路径
        file_path = os.path.join(upload_dir, file_to_upload.name)

        # 将文件保存到指定路径
        with open(file_path, 'wb+') as destination:
            for chunk in file_to_upload.chunks():
                destination.write(chunk)

        unzip_apk(file_to_upload.name)
        file_path = 'filter/'+file_to_upload.name
        file_name = file_to_upload.name

        # 打开文件并创建 FileResponse 对象
        try:
            print(1)
            file = open(file_path, 'rb')
            response = FileResponse(file, as_attachment=True, filename=file_name)
        except FileNotFoundError:
            # 如果文件不存在,可以返回一个错误页面
            return render(request, 'client/online.html', {'error': '文件不存在或权限不足'})
        return response

def upload_files(request):
    if request.method == 'POST':
        file_to_upload = request.FILES['fileToUpload']

        upload_dir = 'apkfilter'
        if not os.path.exists(upload_dir):
            os.makedirs(upload_dir)
        file_path = os.path.join(upload_dir, file_to_upload.name)
        with open(file_path, 'wb+') as destination:
            for chunk in file_to_upload.chunks():
                destination.write(chunk)
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_to_file = {executor.submit(worker, file_path): file_path}
            results = {}
            for future in as_completed(future_to_file):
                file_name, info, apkinfo = future.result()
                if info is None:
                    print(f"Error processing {file_name}: {apkinfo}")
                else:
                    results[file_name] = (info, apkinfo)
                    print(f"Result for {file_name}:")
                    print(f"  Info: {info}")
                    print(f"  APK Info: {apkinfo}")
        for file_name, (info, apkinfo) in results.items():
            attributes = dir(apkinfo)
            attribute_dict = {}
            for attr_name in attributes:
                value = getattr(apkinfo, attr_name, None)
                if not attr_name.startswith("__") and not callable(value):
                    attribute_dict[attr_name] = value
            new_apk = APK()
            for key, value in attribute_dict.items():
                if hasattr(new_apk, key):
                    setattr(new_apk, key, value)
            new_apk.ret = get_ret(info)[0]
            new_apk.save()
        url = reverse('apk_detail', args=[new_apk.id])
        return HttpResponseRedirect(url)

    return render(request, 'client/index.html')

def get_online_ui(request):
    return render(request,'client/online.html')

def get_progresslist(request):
    try:
        files=get_file_list()
        return render(request,'client/progress_list.html',locals())
    except Exception as e:
        return render(request,'client/online.html',locals())

def get_filelist(request):
    try:
        files=get_file_list()
        return render(request,'client/file_list.html',locals())
    except Exception as e:
        return render(request,'client/online.html',locals())

def push2minio_file(request):
    if request.method == 'POST':
        uploaded_file = request.FILES['files1']
        url = "http://localhost:8090/api/v1/file/upload-file"
        try:
            files = {'file': (uploaded_file.name, uploaded_file.read())}
            response = requests.post(url, files=files)
            if response.status_code == 200:
                print("文件转发成功")
                return render(request, 'client/file_list.html')
            else:
                print(f"文件转发失败，状态码：{response.status_code}")
                return render(request, 'client/progress_list.html')
        except Exception as e:
            print(f"转发文件时发生错误：{e}")
            return render(request, 'client/progress_list.html', {'error': '未收到文件'})
    else:
        return render(request, 'client/online.html', {'error': '未收到文件'})

def push2minio_qrcode(request):
    if request.method == 'POST':
        uploaded_file = request.FILES['files2']
        url = "http://localhost:8090/api/v1/file/upload-qrcode"
        try:
            files = {'file': (uploaded_file.name, uploaded_file.read())}
            response = requests.post(url, files=files)
            if response.status_code == 200:
                print("文件转发成功")
                return render(request, 'client/file_list.html')
            else:
                print(f"文件转发失败，状态码：{response.status_code}")
                return render(request, 'client/progress_list.html')
        except Exception as e:
            print(f"转发文件时发生错误：{e}")
            return render(request, 'client/progress_list.html', {'error': '未收到文件'})
    else:
        return render(request, 'client/online.html', {'error': '未收到文件'})

def push2minio_link(request):
    if request.method == 'POST':
        link = request.POST.get('url1')
        url = "http://localhost:8090/api/v1/file/link"
        try:
            data = {'link': link}
            response = requests.post(url, json=data)
            if response.status_code == 200:
                return render(request, 'client/file_list.html')
            else:
                return render(request, 'client/online.html', {'error': '未收到文件'})
        except requests.exceptions.RequestException as e:
            return render(request, 'client/online.html', {'error': '未收到文件'})
        except Exception as e:
            return render(request, 'client/online.html', {'error': '未收到文件'})
